package net.ccfish.jvue.service.impl;

import java.util.List;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;

import net.ccfish.common.enums.YesOrNoEnum;
import net.ccfish.common.mybatis.BaseMapper;
import net.ccfish.jvue.autogen.dao.JvueApiMapper;
import net.ccfish.jvue.autogen.dao.JvueModuleMapper;
import net.ccfish.jvue.autogen.dao.JvuePageMapper;
import net.ccfish.jvue.autogen.dao.JvueSegmentMapper;
import net.ccfish.jvue.autogen.model.JvueApi;
import net.ccfish.jvue.autogen.model.JvueModule;
import net.ccfish.jvue.autogen.model.JvuePage;
import net.ccfish.jvue.autogen.model.JvueSegment;
import net.ccfish.jvue.domain.dao.JvueExPageMapper;
import net.ccfish.jvue.domain.model.JvueExPage;
import net.ccfish.jvue.domain.model.JvueRoleItem;
import net.ccfish.jvue.service.JvueApiService;
import net.ccfish.jvue.service.JvuePageService;
import net.ccfish.jvue.service.model.ModuleAndPages;
import net.ccfish.jvue.service.model.RolePageDetails;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.weekend.WeekendSqls;

/**
 * Generated by Spring Data Generator on 31/01/2018
 */
@Service
@Transactional
public class JvuePageServiceImpl implements JvuePageService {

    @Autowired
    private JvuePageMapper jvuePageMapper;
    @Autowired
    private JvueExPageMapper jvueExPageMapper;

    @Autowired
    private JvueModuleMapper jvueModuleMapper;

    @Autowired
    private JvueSegmentMapper jvueSegmentMapper;
    
    @Autowired
    private JvueApiMapper jvueApiMapper;
    
    @Autowired
    private JvueApiService jvueApiService;

    @Override
    public BaseMapper<JvuePage> baseMapper() {
        return this.jvuePageMapper;
    }

    @Override
    public List<JvueExPage> findAllRootPage() {
        return jvueExPageMapper.findByModuleId(null);
    }

    @Override
    public ModuleAndPages<Integer> findModuleAndPage() {

        ModuleAndPages<Integer> moduleAndPages = new ModuleAndPages<>();
        List<JvueExPage> pages = jvueExPageMapper.findByModuleId(null);

        List<Integer> moduleIds = pages.stream().map(page -> page.getModuleId()).distinct()
                .collect(Collectors.toList());
        
        Example example = new Example.Builder(JvueModule.class)
                .where(WeekendSqls.<JvueModule>custom().andIn(JvueModule::getId, moduleIds))
                .build();

        List<JvueModule> modules = jvueModuleMapper.selectByExample(example);
        
        List<JvueSegment> segments = jvueSegmentMapper.selectAll();

        MultiValueMap<Integer, Integer> segmentMap = new LinkedMultiValueMap<>();
        for (JvueSegment s: segments) {
            segmentMap.add(s.getPageId(), s.getSegmentCode());
        }
        
        moduleAndPages.setPages(pages);
        moduleAndPages.setModules(modules);
        moduleAndPages.setSegments(segmentMap);

        return moduleAndPages;
    }

    @Override
    public List<JvuePage> findByModule(Integer moduleId) {
        Example example = new Example.Builder(JvuePage.class)
                .where(WeekendSqls.<JvuePage>custom().andEqualTo(JvuePage::getModuleId, moduleId).andIsNull(JvuePage::getParentId))
                .build();
        return jvuePageMapper.selectByExample(example);
    }
    
    @Override
    @CacheEvict(value = "JwtUserDetailsService", allEntries = true)
    public void delete(Integer id) {
        
        Assert.notNull(id, "画面ID不能为空");
        // 判断是否在其他表中使用，未使用时，可物理删除；如在page等表里使用，逻辑删除
        JvueSegment segment = new JvueSegment();
        segment.setPageId(id);
        long scount =jvueSegmentMapper.selectCount(segment);
        if (scount > 0L) {
            JvuePage entityResult = jvuePageMapper.selectByPrimaryKey(id);
            if (entityResult != null) {
                //更新
                entityResult.setEnabled(YesOrNoEnum.No.ordinal());
                jvuePageMapper.updateByPrimaryKeySelective(entityResult);
            }
        } else {
            // 同时删除API
            jvueApiService.deleteByPage(id);
            jvuePageMapper.deleteByPrimaryKey(id);
        }
    }

    @Override
    public JvuePage update(Integer id, JvuePage data) {
        // throw new UnsupportedClassVersionError("不支持更新处理");
        JvuePage page = jvuePageMapper.selectByPrimaryKey(id);
        if (page != null) {
            page.setName(data.getName());
            page.setIconClass(data.getIconClass());
            page.setComponent(data.getComponent());
            page.setPath(data.getPath());
            page.setModuleId(data.getModuleId());
            page.setParentId(data.getParentId());
            page.setShowNav(data.getShowNav());
            page.setType(data.getType());
            page.setEnabled(data.getEnabled());
            jvuePageMapper.updateByPrimaryKey(page);
            return page;
        }
        return null;
    }
    @Override
    public RolePageDetails<JvueRoleItem> getAllRoleInfo() {
        
        RolePageDetails<JvueRoleItem> moduleAndPages = new RolePageDetails<>();
        List<JvueExPage> pages = jvueExPageMapper.findByModuleId(null);

        List<Integer> moduleIds = pages.stream().map(page -> page.getModuleId()).distinct()
                .collect(Collectors.toList());


        Example example = new Example.Builder(JvueModule.class)
                .where(WeekendSqls.<JvueModule>custom().andIn(JvueModule::getId, moduleIds))
                .build();

        List<JvueModule> modules = jvueModuleMapper.selectByExample(example);

        List<JvueSegment> segments = jvueSegmentMapper.selectAll();

        MultiValueMap<Integer, JvueRoleItem> segmentMap = new LinkedMultiValueMap<>();
        for (JvueSegment s : segments) {
            JvueRoleItem codeItem = new JvueRoleItem();
            codeItem.setId(s.getId());
            codeItem.setCode(s.getSegmentCode());
            codeItem.setName(s.getName());
            segmentMap.add(s.getPageId(), codeItem);
        }

        List<JvueApi> apis = jvueApiMapper.selectAll();

        MultiValueMap<Integer, JvueRoleItem> apiMap = new LinkedMultiValueMap<>();
        for (JvueApi api: apis) {
            JvueRoleItem codeItem = new JvueRoleItem();
            codeItem.setId(api.getId());
            codeItem.setCode(api.getApiCode());
            codeItem.setName(api.getName());
            apiMap.add(api.getPageId(), codeItem);
        }

        moduleAndPages.setPages(pages);
        moduleAndPages.setModules(modules);
        moduleAndPages.setSegments(segmentMap);
        moduleAndPages.setApis(apiMap);

        return moduleAndPages;
    }
}
